#include "Precompiled.h"
#include "Application.h"

void Demo::View::Load( _In_ Demo::View::EntryPointString wszEntryPoint )
{
}

void Demo::View::Uninitialize( )
{
#ifdef REIGN_DESKTOP
	Safe_Delete(m_pRenderer);
#endif
}

void Demo::View::Initialize( _In_ Demo::AppViewPtr ApplicationView )
{
	m_bActivated = false;
	m_bClosed = false;
	m_bVisible = false;

#ifdef REIGN_DESKTOP // Create demo renderer 
	m_pRenderer = refnew Demo::Renderer();
#else
	m_pRenderer = refnew Demo::Renderer();
#endif
}

void Demo::View::SetWindow( _In_ Demo::AppWindowPtr Window )
{
	Window->VisibilityChanged += refnew Demo::View::AppWindowVisiblityEventHandler( this, &Demo::View::OnWindowVisibilityChanged );
	Window->Activated += refnew Demo::View::AppWindowActivationEventHandler( this, &Demo::View::OnWindowActivatedChanged );
	Window->SizeChanged += refnew Demo::View::AppWindowSizingEventHandler( this, &Demo::View::OnWindowSizeChanged );
	Window->Closed += refnew Demo::View::AppWindowEventHandler( this, &Demo::View::OnWindowClosed );

	Window->PointerWheelChanged += refnew Demo::View::AppWindowPointerEventHandler( this, &Demo::View::OnPointerWheelChanged );
	Window->PointerReleased += refnew Demo::View::AppWindowPointerEventHandler( this, &Demo::View::OnPointerReleased );
	Window->PointerPressed += refnew Demo::View::AppWindowPointerEventHandler( this, &Demo::View::OnPointerPressed );
	Window->PointerMoved += refnew Demo::View::AppWindowPointerEventHandler( this, &Demo::View::OnPointerMoved );

#ifdef REIGN_DESKTOP
	//m_pRenderer->Initialize( Window->GetHandle(), Window->GetLogicalDpi(), D3D_DRIVER_TYPE_REFERENCE );
	m_pRenderer->Initialize( Window->GetHandle(), Window->GetLogicalDpi(), D3D_DRIVER_TYPE_HARDWARE );
	m_pRenderer->SetDpi( Window->GetLogicalDpi() );
#else
	m_pRenderer->Initialize( Window, D3D_DRIVER_TYPE_HARDWARE );
	m_pRenderer->SetDpi( Windows::Graphics::DisplayProperties::LogicalDpi );
#endif

#ifdef GMLABWORKS_6_8
	m_pRenderer->CreateResources();
#endif

	m_pRenderer->CreateBuffers();
	m_pRenderer->CreateShaders();
}

void Demo::View::Run( )
{
#ifdef REIGN_DESKTOP
	Demo::Timer timer;
	timer.Reset();
#else
	Demo::TimerPtr timer = refnew Demo::Timer();
	timer->Reset();
#endif


	Demo::AppWindow::GetForCurrentThread()->Activate();
	
	while ( !m_bClosed )
	{
		Demo::AppWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(
			AppWindowProcessEventsOption::ProcessAllIfPresent
			);
		
#ifdef REIGN_DESKTOP
		timer.Update();
#else
		timer->Update();
#endif

#ifdef REIGN_DESKTOP
		m_pRenderer->OnFrameMove( &timer );
#else
		m_pRenderer->OnFrameMove( timer );
#endif

		m_pRenderer->OnFrame();
	}
}

void Demo::View::OnPointerMoved( 
	_In_ Demo::AppWindowPtr pWindow,
	_In_ Demo::View::AppWindowPointerEventArgsPtr pArgs
	)
{
#ifdef GMLABWORKS_6_8
	m_pRenderer->OnPointerMoved(pArgs);
#endif

	m_pRenderer->OnPointerMoved(
		pArgs->CurrentPoint->Position->X, 
		pArgs->CurrentPoint->Position->Y
		);
}

void Demo::View::OnPointerPressed( 
	_In_ Demo::AppWindowPtr pWindow,
	_In_ Demo::View::AppWindowPointerEventArgsPtr pArgs
	)
{
#ifdef GMLABWORKS_6_8
	//PrintToDebugWindowOnly8( "Demo::View::OnPointerPressed" );
	m_pRenderer->OnPointerPressed(pArgs);
#endif

	if ( pArgs->CurrentPoint->Properties->IsLeftButtonPressed )
	{
		m_pRenderer->OnPointerLeftButtonPressed(
			pArgs->CurrentPoint->Position->X, 
			pArgs->CurrentPoint->Position->Y
			);
	}
	else if ( pArgs->CurrentPoint->Properties->IsRightButtonPressed )
	{
		m_pRenderer->OnPointerRightButtonPressed(
			pArgs->CurrentPoint->Position->X, 
			pArgs->CurrentPoint->Position->Y
			);
	}
	else if ( pArgs->CurrentPoint->Properties->IsMiddleButtonPressed )
	{
		m_pRenderer->OnPointerMiddleButtonPressed(
			pArgs->CurrentPoint->Position->X, 
			pArgs->CurrentPoint->Position->Y
			);
	}
}

void Demo::View::OnPointerReleased( 
	_In_ Demo::AppWindowPtr pWindow,
	_In_ Demo::View::AppWindowPointerEventArgsPtr pArgs
	)
{
	if ( !pArgs->CurrentPoint->Properties->IsLeftButtonPressed )
	{
		m_pRenderer->OnPointerLeftButtonReleased();
	}
	else if ( !pArgs->CurrentPoint->Properties->IsRightButtonPressed )
	{
		m_pRenderer->OnPointerRightButtonReleased();
	}
	else if ( !pArgs->CurrentPoint->Properties->IsMiddleButtonPressed )
	{
		m_pRenderer->OnPointerMiddleButtonReleased();
	}

	//PrintToDebugWindowOnly8( "Demo::View::OnPointerReleased" );
}

void Demo::View::OnPointerWheelChanged( 
	_In_ Demo::AppWindowPtr pWindow,
	_In_ Demo::View::AppWindowPointerEventArgsPtr pArgs
	)
{
#ifdef GMLABWORKS_6_8
	//PrintToDebugWindowOnly8( "Demo::View::OnPointerWheelChanged" );
	m_pRenderer->OnPointerWheelChanged(pArgs);
#endif

	m_pRenderer->OnPointerWheelChanged(
		pArgs->CurrentPoint->Properties->MouseWheelDelta
		);
}

void Demo::View::OnWindowSizeChanged(
	_In_ Demo::AppWindowPtr pWindow,
	_In_ Demo::View::AppWindowSizingEventArgsPtr pArgs
	)
{
#ifdef GMLABWORKS_6_8
	m_pRenderer->OnWindowsSizeChanged();
#endif
}

void Demo::View::OnWindowActivatedChanged(
	_In_ Demo::AppWindowPtr pWindow,
	_In_ Demo::View::AppWindowActivationEventArgsPtr pArgs
	)
{
	m_bActivated = pArgs->WindowActivationState != Demo::View::AppWindowActivationState::Deactivated;
}

void Demo::View::OnWindowVisibilityChanged(
	_In_ Demo::AppWindowPtr pWindow,
	_In_ Demo::View::AppWindowVisibilityEventArgsPtr pArgs
	)
{
	m_bVisible = pArgs->Visible;
}

void Demo::View::OnWindowClosed(
	_In_ Demo::AppWindowPtr pWindow,
	_In_ Demo::View::AppWindowEventArgsPtr pArgs
	)
{
	m_bClosed = true;

#ifdef GMLABWORKS_6_8
	m_pRenderer->OnExit();
#endif
}

Demo::IViewPtr Demo::Provider::CreateView( )
{
	return( refnew Demo::View );
}

#ifdef REIGN_DESKTOP
Int32 main( _In_ SharedStringArray Args )
#else
[Platform::MTAThreadAttribute]
Int32 main( _In_ Platform::Array<Platform::String^>^ Args )
#endif
{
#if defined REIGN_DEBUG && defined REIGN_DESKTOP // Debug + Desktop
    _CrtSetDbgFlag( // Enable run-time memory check for debug builds.
		_CRTDBG_ALLOC_MEM_DF | // Enable debug allocation
		_CRTDBG_LEAK_CHECK_DF // Enable checking for memory leaks
		);
#endif // All configurations

	Demo::App::Run( // Pass the app view provider to core app
		refnew Demo::Provider() // App view provider
		);

	return( EXIT_SUCCESS );
}
